package cn.com.wangluotongxin.merchants.service.impl;

import cn.com.wangluotongxin.common.constants.CommonConstant;
import cn.com.wangluotongxin.common.exceptions.BadResponseException;
import cn.com.wangluotongxin.common.utils.TenantUtils;
import cn.com.wangluotongxin.merchants.eureka.form.AddMerchantsMenuEditForm;
import cn.com.wangluotongxin.merchants.eureka.form.AddMerchantsMenuForm;
import cn.com.wangluotongxin.merchants.model.MerchantsMenu;
import cn.com.wangluotongxin.merchants.mapper.MerchantsMenuMapper;
import cn.com.wangluotongxin.merchants.model.MerchantsRoleMenu;
import cn.com.wangluotongxin.merchants.service.IMerchantsMenuService;
import cn.com.wangluotongxin.merchants.service.IMerchantsRoleMenuService;
import cn.com.wangluotongxin.merchants.vo.DMerchantsMenuVo;
import cn.com.wangluotongxin.merchants.vo.MenuVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商户管理-菜单权限 服务实现类
 * </p>
 *
 * @author AutoGenerator
 * @since 2024-04-26
 */
@Service
public class MerchantsMenuServiceImpl extends ServiceImpl<MerchantsMenuMapper, MerchantsMenu> implements IMerchantsMenuService {

    @Autowired
    private IMerchantsRoleMenuService roleMenuService;

    @Override
    public List<MerchantsMenu> getByUser(Integer userId) {
        return baseMapper.getByUser(userId);
    }

    @Override
    public List<MerchantsMenu> getAllMenus() {
        return baseMapper.getAllMenus();
    }

    @Override
    public void initMenu(String targetTenantId) {
        List<MerchantsMenu> sourceMenus = this.getSourceMenus(CommonConstant.MYBATIS_TENANT_MASTER);

        TenantUtils.set(targetTenantId, targetTenantId);
        List<MerchantsMenu> oldMenus = this.list(new LambdaQueryWrapper<MerchantsMenu>()
                .in(MerchantsMenu::getSourceId, sourceMenus.stream().map(item-> { return item.getId(); })
                        .collect(Collectors.toList())));
        List<Integer> updateMenuIds = oldMenus.stream().map(item-> { return item.getSourceId(); }).collect(Collectors.toList());
        List<MerchantsMenu> updateMenus = sourceMenus.stream().filter(item-> updateMenuIds.contains(item.getId())).map(item-> {
            MerchantsMenu oldMenu = oldMenus.stream().filter(old->old.getSourceId().equals(item.getId())).findFirst().orElse(null);
            MerchantsMenu updateMenu = new MerchantsMenu();
            BeanUtils.copyProperties(item, updateMenu);
            updateMenu.setId(oldMenu.getId());
            return updateMenu;
        }).collect(Collectors.toList());

        List<MerchantsMenu> saveMenus = sourceMenus.stream().filter(item-> !updateMenuIds.contains(item.getId())).collect(Collectors.toList());
        if(saveMenus != null && saveMenus.size() > 0) {
            List<MerchantsMenu> menus = saveMenus.stream().map(item -> {
                MerchantsMenu menu = new MerchantsMenu();
                BeanUtils.copyProperties(item, menu);
                menu.setSourceId(item.getId());
                menu.setId(null);
                return menu;
            }).collect(Collectors.toList());
            this.saveBatch(menus);
        }

        if(updateMenus != null && updateMenus.size() > 0){
            this.updateBatchById(updateMenus);
        }

        baseMapper.upMenuParentId();
        TenantUtils.remove();
    }

    @Override
    public List<DMerchantsMenuVo> getList() {
        return baseMapper.getList();
    }

    @Override
    public DMerchantsMenuVo detail(Integer id) {
        return baseMapper.detail(id);
    }

    @Override
    public void add(AddMerchantsMenuForm form) {
        MerchantsMenu menu = new MerchantsMenu();
        BeanUtils.copyProperties(form, menu);
        this.save(menu);
    }

    @Override
    public void edit(AddMerchantsMenuEditForm form) {
        MerchantsMenu menu = new MerchantsMenu();
        BeanUtils.copyProperties(form, menu);
        this.updateById(menu);
    }

    @Override
    public void delete(Integer menuId) {
        MerchantsMenu merchantsMenu = this.getOne(new LambdaQueryWrapper<MerchantsMenu>()
                .eq(MerchantsMenu::getParentId, menuId)
                .last("limit 0,1"));
        Assert.isNull(merchantsMenu, "请从最低级开始删除");

        this.removeById(menuId);

        roleMenuService.remove(new LambdaQueryWrapper<MerchantsRoleMenu>()
                .eq(MerchantsRoleMenu::getMenuId, menuId));
    }

    @Override
    public List<MenuVo> getTreeList() {
        return baseMapper.getTreeList();
    }

    private List<MerchantsMenu> getSourceMenus(String masterDataSource) {
        TenantUtils.set(masterDataSource, masterDataSource);
        List<MerchantsMenu> menus = this.list();
        if(menus == null || menus.size() <= 0) {
            throw new BadResponseException("未获取到来源菜单信息");
        }
        TenantUtils.remove();
        return menus;
    }
}
